package cn.sfrog.project.biz.web.controller;

import cn.sfrog.common.constant.Constants;
import cn.sfrog.common.core.controller.BaseController;
import cn.sfrog.common.core.domain.AjaxResult;
import cn.sfrog.common.core.domain.ApiAjaxResult;
import cn.sfrog.common.core.domain.entity.SysUser;
import cn.sfrog.common.core.page.TableDataInfo;
import cn.sfrog.common.core.redis.RedisCache;
import cn.sfrog.common.utils.SecurityUtils;
import cn.sfrog.common.utils.StringUtils;
import cn.sfrog.project.biz.admin.domain.BizUserEnsureMoney;
import cn.sfrog.project.biz.admin.service.IBizUserInviteRecordService;
import cn.sfrog.project.biz.admin.service.IBizUserProfessionRecordService;
import cn.sfrog.project.biz.admin.utils.PhoneFormatCheckUtils;
import cn.sfrog.project.biz.admin.utils.sms.SmsResponse;
import cn.sfrog.project.biz.admin.utils.sms.SmsUtils;
import cn.sfrog.project.biz.web.service.AppUserService;
import cn.sfrog.project.biz.web.vo.AppSendCodeVO;
import cn.sfrog.project.biz.web.vo.AppSubmitIdCardInfoVo;
import cn.sfrog.project.biz.web.vo.AppSubmitJobAuthFormVo;
import cn.sfrog.project.biz.web.vo.account.AppDoctorAuthStatusVO;
import cn.sfrog.project.biz.web.vo.account.AppUserAuthStatusVO;
import cn.sfrog.project.biz.web.vo.account.AppUserInviteResultVO;
import cn.sfrog.project.biz.web.vo.index.AppAuthRecordResultVO;
import cn.sfrog.project.biz.web.vo.index.AppDoctorProfessionalVO;
import cn.sfrog.project.biz.web.vo.index.AppJobAuthResultVO;
import cn.sfrog.system.domain.vo.app.AppUpdateUserInfoVO;
import cn.sfrog.system.domain.vo.app.AppUpdateUserPhoneVO;
import cn.sfrog.system.domain.vo.app.AppUserLoginFormVO;
import cn.sfrog.system.domain.vo.app.AppUserRegisterFormVO;
import cn.sfrog.system.mapper.SysUserMapper;
import cn.sfrog.system.service.ISysUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;


@Slf4j
@RestController
@RequestMapping("/api/user")
@Api(value = "/api/user", tags = "APP用户相关")
public class AppUserController extends BaseController {
    @Resource
    private ISysUserService userService;
    @Resource
    private AppUserService appUserService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private IBizUserProfessionRecordService bizUserProfessionRecordService;
    @Autowired
    private IBizUserInviteRecordService bizUserInviteRecordService;
    @Resource
    private SysUserMapper sysUserMapper;


    @Value("${sms.url}")
    private String url;

    @Value("${sms.appKey}")
    private String appKey;

    @Value("${sms.appSecret}")
    private String appSecret;

    @Value("${sms.sender}")
    private String sender;

    @Value("${sms.templateId}")
    private String templateId;

    @Value("${sms.signature}")
    private String signature;


    @ApiOperation(value = "发送注册/登录/修改手机号验证码", httpMethod = "GET")
    @ApiResponses({
            @ApiResponse(code = 500, message = "错误"),
            @ApiResponse(code = 200, message = "操作成功", response = AjaxResult.class)
    })
    @GetMapping("/sendCode")
    public ApiAjaxResult sendCode( @Validated AppSendCodeVO sendCodeVo) {
        if (!PhoneFormatCheckUtils.isChinaPhoneLegal(sendCodeVo.getPhone())) {
            return ApiAjaxResult.success("手机号码有误,请重新输入");
        }
        String randomNumberCode = "";
        String key = "";
        // 发送验证码是否存在 如果存在
        Object cacheLogin = redisCache.getCacheObject(Constants.LOGIN_CACHE_PHONE_CODE_KEY + sendCodeVo.getPhone());
        Object cacheRegister = redisCache.getCacheObject(Constants.REGISTER_CACHE_PHONE_CODE_KEY + sendCodeVo.getPhone());
        if(cacheLogin != null){
            //删除登录的验证码（防止用户试探性登录时验证码没过期，导致的没法发送验证码）
            redisCache.deleteObject(Constants.LOGIN_CACHE_PHONE_CODE_KEY + sendCodeVo.getPhone());
        }
        if(cacheRegister != null){
            //删除注册的验证码（防止用户尝试登录时无法获取验证码，导致无法发送验证码）
            redisCache.deleteObject(Constants.REGISTER_CACHE_PHONE_CODE_KEY + sendCodeVo.getPhone());
        }
        if(Constants.TYPE_REGISTER.equals(sendCodeVo.getType())){
            key = Constants.REGISTER_CACHE_PHONE_CODE_KEY;
        }else if(Constants.TYPE_LOGIN.equals(sendCodeVo.getType())){
            key = Constants.LOGIN_CACHE_PHONE_CODE_KEY;
        }else if(Constants.TYPE_UPDATE_PHONE.equals(sendCodeVo.getType())){
            key = Constants.UPDATE_CACHE_PHONE_CODE_KEY;
        }
       // String key = StringUtils.equals(Constants.TYPE_REGISTER, sendCodeVo.getType()) ? Constants.REGISTER_CACHE_PHONE_CODE_KEY : Constants.LOGIN_CACHE_PHONE_CODE_KEY;

        Object cacheValue = redisCache.getCacheObject(key + sendCodeVo.getPhone());
//        默认本人所有验证码过期
//        redisCache.deleteObject(key + sendCodeVo.getPhone());
        if (null == cacheValue) {
            randomNumberCode = RandomStringUtils.randomNumeric(6);
            // 发送验证码短信
            String templateParas = "[\"".concat(randomNumberCode).concat("\"]");
            SmsResponse response = SmsUtils.sendSms(url, appKey, appSecret, sender, templateId, signature, templateParas, sendCodeVo.getPhone());

            if (response == null) {
                return ApiAjaxResult.error("验证码发送失败！");
            } else if (!Constants.PHONE_CODE_SUCCESS.equals(response.getCode())) {
                return ApiAjaxResult.error("验证码发送失败！");
            }
            redisCache.setCacheObject(key + sendCodeVo.getPhone(), randomNumberCode, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        } else {
            return ApiAjaxResult.error("您的验证码仍在有效期内，请不要频繁发送");
        }
        return ApiAjaxResult.success("验证码发送成功,您的验证码为"+randomNumberCode);
    }


    @PostMapping("/register")
    @ApiOperation("APP用户注册")
    public ApiAjaxResult userRegister(@RequestBody @Validated AppUserRegisterFormVO registerFormVO){
        Boolean flag = appUserService.appUserRegister(registerFormVO);
        return ApiAjaxResult.success(flag);
    }


    /**
     * APP用户登录
     * @param loginFormVO
     * @return
     */
    @PostMapping("/login")
    @ApiOperation("APP用户登录")
    public ApiAjaxResult login(@RequestBody @Validated AppUserLoginFormVO loginFormVO){
        String token  = appUserService.appUserLogin(loginFormVO);
        return ApiAjaxResult.success("登录成功",token);
    }

    /**
     * 获取用户信息
     * @return
     */
    @PostMapping("/getUserInfo")
    @ApiOperation("获取用户信息")
    public ApiAjaxResult getUserInfo(){
        return ApiAjaxResult.success(appUserService.getUserInfo());
    }

    /**
     * 身份认证
     * @param vo
     * @return
     */
    @PostMapping("/submitIdCardInfo")
    @ApiOperation("身份认证接口")
    public ApiAjaxResult submitIdCardInfo(@RequestBody @Validated AppSubmitIdCardInfoVo vo){
        return ApiAjaxResult.success(appUserService.submitIdCardInfo(vo));
    }

    /**
     * 取消身份证认证接口
     * @return
     */
    @PostMapping("/cancelIdCardAuth")
    @ApiOperation("取消身份认证接口")
    public ApiAjaxResult cancelIdCardAuth(){
        return ApiAjaxResult.success(appUserService.cancelIdCardAuth());
    }

    /**
     * APP修改个人信息
     * @param userInfoVO
     * @return
     */
    @PostMapping("/updateUserInfo")
    @ApiOperation("修改个人信息")
    public ApiAjaxResult updateUserInfo(@Validated @RequestBody AppUpdateUserInfoVO userInfoVO){
        return ApiAjaxResult.success(appUserService.updateUserInfo(userInfoVO));
    }

    @PostMapping("/updateUserPhone")
    @ApiOperation("修改手机号")
    public ApiAjaxResult updateUserPhone(@Validated @RequestBody AppUpdateUserPhoneVO vo){
        return ApiAjaxResult.success(appUserService.updateUserPhone(vo));
    }

    @PostMapping("/submitJobAuth")
    @ApiOperation("执业资质认证[陪诊,护工,医生]")
    public ApiAjaxResult submitJobAuth(@RequestBody @Validated AppSubmitJobAuthFormVo form){
        return appUserService.submitJobAuth(form);
    }

    @GetMapping("/getJobAuthList")
    @ApiOperation("获取已认证职业资质列表")
    public TableDataInfo<List<AppJobAuthResultVO>> getJobAuthList(){
        Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
        SysUser sysUser = sysUserMapper.selectUserById(userId);
        startPage();
        List<AppJobAuthResultVO> jobAuthResultVOList = bizUserProfessionRecordService.selectAppJobAuthList(userId,sysUser.getUserType());
        return getDataTable(jobAuthResultVOList);
    }
    @GetMapping("/getAuthRecord")
    @ApiOperation("认证记录")
    public TableDataInfo<List<AppAuthRecordResultVO>> getAuthRecord(){
        Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
        SysUser sysUser = sysUserMapper.selectUserById(userId);
        startPage();
        List<AppAuthRecordResultVO> authRecordList = bizUserProfessionRecordService.selectAppAuthRecord(userId,sysUser.getUserType());
        return getDataTable(authRecordList);
    }
    @GetMapping("/getInviteList")
    @ApiOperation("获取邀请列表")
    public TableDataInfo<AppUserInviteResultVO> getInviteList(){
        Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
        startPage();
        List<AppUserInviteResultVO> inviteList = bizUserInviteRecordService.selectAppUserInviteList(userId);
        return getDataTable(inviteList);
    }
    @GetMapping("/getAuthStatus")
    @ApiOperation("获取用户认证状态")
    public ApiAjaxResult<AppUserAuthStatusVO> getAuthStatus(){
        AppUserAuthStatusVO statusVO = new AppUserAuthStatusVO();
        statusVO.setStatus(false);
        statusVO.setType(1);
        Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
        SysUser sysUser = sysUserMapper.selectUserById(userId);
        if(Constants.IS_VERIFIED_YES.equals(sysUser.getIsVerified()) && Constants.AUDIT_STATUS_PASS.equals(sysUser.getAuditStatus())){
            statusVO.setStatus(true);
        }else {
            return  ApiAjaxResult.success("您尚未完成实名认证",statusVO);
        }
        return ApiAjaxResult.success(statusVO);
    }
    @GetMapping("/getEnsureMoneyStatus")
    @ApiOperation("获取是否完成缴纳保证金")
    public ApiAjaxResult<AppUserAuthStatusVO> getEnsureMoneyStatus(){
        AppUserAuthStatusVO statusVO = new AppUserAuthStatusVO();
        statusVO.setStatus(false);
        statusVO.setType(2);
        Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
        //查询保证金信息
        LambdaQueryWrapper<BizUserEnsureMoney> lambdaQueryWrapper = new LambdaQueryWrapper<BizUserEnsureMoney>()
                .eq(BizUserEnsureMoney::getUserId,userId)
                .orderByDesc(BizUserEnsureMoney::getCreateTime)
                .last(" limit 1");
        BizUserEnsureMoney money = BizUserEnsureMoney.DAO.selectOne(lambdaQueryWrapper);
        if(money !=null && (BizUserEnsureMoney.PAID.equals(money.getPayStatus()) || BizUserEnsureMoney.REFUNDING.equals(money.getPayStatus()))){
            statusVO.setStatus(true);
        }else {
            return  ApiAjaxResult.success("您尚未缴纳保证金",statusVO);
        }

        return ApiAjaxResult.success(statusVO);
    }
    @GetMapping("/getAllStatus")
    @ApiOperation("获取所有的状态")
    public ApiAjaxResult getAllStatus(){
        return appUserService.getAllStatus();
    }
    @GetMapping("/getDoctorProfession")
    @ApiOperation("获取医生是否完成职业资质认证")
    public ApiAjaxResult<AppDoctorAuthStatusVO> getDoctorProfession(){
        AppDoctorAuthStatusVO statusVO = new AppDoctorAuthStatusVO();
        Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
        AppDoctorProfessionalVO vo =  bizUserProfessionRecordService.selectLastProfession(userId);
        if(StringUtils.isNull(vo)){
            statusVO.setStatus(false);
            return  ApiAjaxResult.success("您尚未完成职业资质认证",statusVO);
        }else {
            statusVO.setStatus(true);
        }
        return ApiAjaxResult.success(statusVO);
    }
    @PostMapping("/userLogout")
    @ApiOperation("用户注销")
    public ApiAjaxResult userLogout(){
        Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
        return ApiAjaxResult.success(userService.userLogout(userId));
    }
}
